package org.railage.client.beans;

import java.util.Arrays;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.railage.common.dto.UserDTO;
import org.railage.common.protocol.Result;
import org.railage.server.services.RouteService;
import org.railage.server.services.StationService;
import org.railage.server.services.TicketService;

@ManagedBean(name = "buyTicket")
@ViewScoped
public class BuyTicketBean {

	private static final Logger log = Logger.getLogger(BuyTicketBean.class);

	private RouteService routeService = new RouteService();
	private StationService stationService = new StationService();
	private TicketService ticketService = new TicketService();

	private int tripID;
	private String routeName;
	private int ticketsCount;
	private String selectedStationA;
	private String selectedStationB;
	private String[] stationsA;
	private String[] stationsB;

	private boolean isEmpty(String param) {
		boolean result = true;
		if (param != null) {
			if (!param.equals("")) {
				result = false;
			}
		}
		return result;
	}

	public void init() {
		routeName = routeService.getRouteByTripID(tripID);
		stationsA = stationService.getOrderedStationsOfTrip(tripID);
		stationsB = null;
		ticketsCount = 0;
		selectedStationA = null;
		selectedStationB = null;
	}

	public void isSelectedStationA() {
		if (!isEmpty(selectedStationA)) {
			log.debug("Station A: " + selectedStationA);
			List<String> stations = Arrays.asList(stationsA);
			int departureIndex = stations.indexOf(selectedStationA);
			stationsB = new String[stationsA.length - departureIndex - 1];
			System.arraycopy(stationsA, departureIndex + 1, stationsB, 0,
					stationsA.length - departureIndex - 1);
		} else {
			stationsB = null;
		}
	}

	public void isSelectedStationB() {
		if (!isEmpty(selectedStationB)) {
			log.debug("Station B: " + selectedStationB);
			ticketsCount = ticketService
					.getAvailableTicketsNumber(new String[] {
							String.valueOf(tripID), selectedStationA,
							selectedStationB });
			log.debug("Tickets count: " + String.valueOf(ticketsCount));
		} else {
			ticketsCount = 0;
		}
	}

	public void buy() {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		FacesMessage message = null;
		RequestContext context = RequestContext.getCurrentInstance();
		
		boolean emptyA = isEmpty(selectedStationA);
		boolean emptyB = isEmpty(selectedStationB);
		if (emptyA || emptyB) {
			if (emptyA) {
				message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
						"Please select departure station", "");
				facesContext.addMessage(null, message);
			}
			if (emptyB) {
				message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
						"Please select destination station", "");
				facesContext.addMessage(null, message);
			}
			context.update("buyTicketForm:buyTicketMessages");
			return;
		}	

		UserDTO user = (UserDTO) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap()
				.get(AuthBean.SESSION_USER_PARAM);
		Result result = ticketService.buyTicket(new Object[] { user.getId(),
				tripID, selectedStationA, selectedStationB });

		if (result.isNoError()) {
			context.execute("buyTicket.hide();");
			message = new FacesMessage(FacesMessage.SEVERITY_INFO,
					result.getResult(), "");
			facesContext.addMessage(null, message);
			context.update("form:messages");
			init();
		} else {
			message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
					result.getResult(), "");
			facesContext.addMessage(null, message);
			context.update("buyTicketForm:buyTicketMessages");
		}
		log.debug("Buy result: " + result.getResult());

	}

	public int getTripID() {
		return tripID;
	}

	public void setTripID(int tripID) {
		this.tripID = tripID;
		init();
	}

	public int getTicketsCount() {
		return ticketsCount;
	}

	public String getSelectedStationA() {
		return selectedStationA;
	}

	public void setSelectedStationA(String selectedStationA) {
		this.selectedStationA = selectedStationA;
	}

	public String getSelectedStationB() {
		return selectedStationB;
	}

	public void setSelectedStationB(String selectedStationB) {
		this.selectedStationB = selectedStationB;
	}

	public String getRouteName() {
		return routeName;
	}

	public String[] getStationsA() {
		return stationsA;
	}

	public String[] getStationsB() {
		return stationsB;
	}

}
